#include "WriterTopoConvertHelper.h"
#include <topology/TopoEdge.hpp>
#include <topology/TopoFace.hpp>
#include <topology/TopoWire.hpp>
#include "position.hxx"
#include "vector.hxx" // Ensure this header file defines SPAvector
#include "coedge.hxx"
#include "bs3curve.hxx"
#include <common/AxisT.hpp>
#include <geometry/Geom3Curve.hpp>
#include <geometry/Geom3Line.hpp>
#include <cstrapi.hxx>
#include <geometry/Geom3Ellipse.hpp>
#include <geometry/Geom3Circle.hpp>
#include <geometry/Geom3BSplineCurve.hpp>
#include "unitvec.hxx"
#include "heldef.hxx"
#include <geometry/Geom3BoundedSurface.hpp>
#include <geometry/Geom3ConicalSurface.hpp>
#include <geometry/Geom3Plane.hpp>
#include <geometry/Geom3SphericalSurface.hpp>
#include <geometry/Geom3ToroidalSurface.hpp>
#include <functional>
#include "topology/TopoTool.hpp"
#include <geometry/Geom3Surface.hpp>
#include <geometry/Geom3BSplineSurface.hpp>
#include "splsurf.hxx"
#include <position.hxx>
#include <occtio/OCCTTool.hpp>
#include <healing/ShapeFixTool.hpp>
#include "topology/BRepTool.hpp"
#include "geometry/Geom3CylindricalSurface.hpp"
#include "topology/TopoExplorerTool.hpp"
#include "topology/TopoExplorer.hpp"
#include "topology/TopoCast.hpp"
#include <SPAIopPartExporter.h>
#include <SPAIopResult.h> // Add this line to include the definition of SPAIopResult
#include <SPAIopPolicy.h> // Add this line to include the definition of SPAIopPolicy
#include <SPAIopAcisOutputPart.h>
#include <core/InterOpUtils.h>
#include "InterOpWriter.h"
#include "boolapi.hxx"
#include "common/logger.h"
#include <modeling/TransformShape.hpp>
#include <math/Plane.hpp>
#include <pladef.hxx>
#include <kernapi.hxx>
#include "ellipse.hxx"
#include "point.hxx"
#include "plane.hxx"
#include <geometry/Geom3TrimmedCurve.hpp>
#include <cone.hxx>
#include <torus.hxx>
#include <sphere.hxx>
#include <cur_sur.hxx>
#include <spldef.hxx>
#include "spline.hxx"
#include <sp3srtn.hxx>
#include <sps3srtn.hxx>
#include <geometry/Geom3TrimmedSurface.hpp>
AMCAX_EXCHANGE_NAMESPACE_BEGIN

namespace InterOp::WriterGeometryConvertHelper
{
    SPAposition ConvertPoint(const AMCAX::Point3 &pt)
    {
        SPAposition res(pt.X(), pt.Y(), pt.Z());
        return std::move(res);
    }
    SPAvector ConvertVector(const AMCAX::Axis3 &axis)
    {
        SPAvector res(axis.Direction().X(), axis.Direction().Y(), axis.Direction().Z());
        return res;
    }
    SPAvector ConvertVector(const AMCAX::Direction3 &dir3)
    {
        SPAvector res(dir3.X(), dir3.Y(), dir3.Z());
        return res;
    }
    SPAvector ConvertVector(const AMCAX::Vector3 &vector)
    {
        SPAvector res(vector.X(), vector.Y(), vector.Z());
        return res;
    }
    double ConvertToAngle(double rad)
    {
        return rad * 180.0 / M_PI; // 起始角
    }
}

namespace InterOp::WriterTopoConvertHelper
{
    std::string curveTypeToString(CurveType type)
    {
        switch (type)
        {
        case CurveType::Undefined:
            return "Undefined";
        case CurveType::Line:
            return "Line";
        case CurveType::Circle:
            return "Circle";
        case CurveType::Ellipse:
            return "Ellipse";
        case CurveType::Parabola:
            return "Parabola";
        case CurveType::Hyperbola:
            return "Hyperbola";
        case CurveType::BezierCurve:
            return "BezierCurve";
        case CurveType::BSplineCurve:
            return "BSplineCurve";
        case CurveType::TrimmedCurve:
            return "TrimmedCurve";
        case CurveType::OffsetCurve:
            return "OffsetCurve";
        case CurveType::OtherCurve:
            return "OtherCurve";
            // 如果所有枚举值已处理，无需default分支
        }
        // 处理非法枚举值（如强制转换的无效值）
        return "Undefined"; // 或抛出异常
    }
    std::string surfaceTypeToString(SurfaceType type)
    {
        switch (type)
        {
        case SurfaceType::Undefined:
            return "Undefined";
        case SurfaceType::Plane:
            return "Plane";
        case SurfaceType::Cylinder:
            return "Cylinder";
        case SurfaceType::Cone:
            return "Cone";
        case SurfaceType::Sphere:
            return "Sphere";
        case SurfaceType::Torus:
            return "Torus";
        case SurfaceType::SurfaceOfExtrusion:
            return "SurfaceOfExtrusion";
        case SurfaceType::SurfaceOfRevolution:
            return "SurfaceOfRevolution";
        case SurfaceType::BezierSurface:
            return "BezierSurface";
        case SurfaceType::BSplineSurface:
            return "BSplineSurface";
        case SurfaceType::TrimmedSurface:
            return "TrimmedSurface";
        case SurfaceType::OffsetSurface:
            return "OffsetSurface";
        case SurfaceType::OtherSurface:
            return "OtherSurface";

        default:
            return "Unknown"; // 处理未知类型
        }
    }

    EDGE *ConvertEdge(const AMCAX::TopoEdge &edge)
    {
        double fp, lp;
        std::shared_ptr<Geom3Curve> curve = TopoTool::Curve(edge, fp, lp);
        if(curve == nullptr)
        {
            LOG_ERROR("curve is null") ;
            return nullptr;
        }
    
        AMCAX::CurveType curveType = curve->Type();
        LOG_DEBUG("edgeType:{}", curveTypeToString(curveType));
        REVBIT sense = edge.Orientation() == AMCAX::OrientationType::Reversed ? REVERSED : FORWARD; 
        AMCAX::Point3 startPoint, endPoint;
        curve->D0(fp,startPoint);
        curve->D0(lp,endPoint);

        if(startPoint.IsEqual(endPoint, 1e-4))
        {
            return nullptr; // 如果起始和结束参数相同，返回空指针   
        }

        // LOG_DEBUG("startPoint: ({}, {}, {}), endPoint: ({}, {}, {}), sense: {}",
        //   startPoint.X(), startPoint.Y(), startPoint.Z(),
        //   endPoint.X(), endPoint.Y(), endPoint.Z(),
        //   (sense == REVERSED) ? "REVERSED" : "FORWARD");
        if (curveType == AMCAX::CurveType::Line)
        {
            return ConvertStraightLine(curve, fp, lp);
        }
        else if (curveType == AMCAX::CurveType::Ellipse)
        {
            return ConvertEllipse(curve, fp, lp);
        }
        else if (curveType == AMCAX::CurveType::Circle)
        {
            return ConvertCircle(curve, fp, lp);
        }
        else if (curveType == AMCAX::CurveType::BSplineCurve)
        {
            return ConvertBSplineCurve(curve, fp, lp);
        }
        else
        {
            LOG_ERROR("unsupport curve type:{}", curveTypeToString(curveType));
        }
        return nullptr;
    }

    EDGE *ConvertStraightLine(std::shared_ptr<Geom3Curve> curve, double fp, double lp)
    {
        std::shared_ptr<AMCAX::Geom3Line> curveLine = std::dynamic_pointer_cast<AMCAX::Geom3Line>(curve);
        auto fp2 = curveLine->FirstParameter();
        auto lp2 = curveLine->LastParameter();

        AMCAX::Point3 sp = curveLine->Value(fp);
        AMCAX::Point3 ep = curveLine->Value(lp);
        AMCAX::Point3 sp1, ep1;
        curveLine->D0(fp, sp1);
        curveLine->D0(lp, ep1);
        SPAposition startPoint = InterOp::WriterGeometryConvertHelper::ConvertPoint(sp);
        SPAposition endPoint = InterOp::WriterGeometryConvertHelper::ConvertPoint(ep);
        EDGE *res;
        // api_curve_line(startPoint, endPoint, res);
        api_mk_ed_line(startPoint, endPoint, res);

        return res;
    }

    EDGE *ConvertEllipse(std::shared_ptr<Geom3Curve> curve, double fp, double lp)
    {
        // LOG_DEBUG("ConvertEllipse");
        std::shared_ptr<AMCAX::Geom3Ellipse> curveEllipse = std::dynamic_pointer_cast<AMCAX::Geom3Ellipse>(curve);
        EDGE *res;
        SPAposition center, major;
        double ratio, startAngle, endAngle;

        // 获取椭圆的圆心
        AMCAX::Point3 c = curveEllipse->Location();
        center = InterOp::WriterGeometryConvertHelper::ConvertPoint(c);

        // 获取椭圆的长半径
        double majorRadius = curveEllipse->MajorRadius();
        double minorRadius = curveEllipse->MinorRadius();
        ratio = majorRadius / minorRadius;
        // 获取焦点
        AMCAX::Point3 focus1 = curveEllipse->Focus1();
        AMCAX::Point3 focus2 = curveEllipse->Focus2();

        // 计算主轴方向向量（焦点方向）
        AMCAX::DirectionT<double, 3> d;
        AMCAX::Vector3 majorVec(focus1[0] - focus2[0],
                                focus1[1] - focus2[1],
                                focus1[2] - focus2[2]);

        // 归一化主轴方向向量
        majorVec.Normalize();
        AMCAX::Point3 majorPoint(
            c.X() + majorVec.X() * majorRadius,
            c.Y() + majorVec.Y() * majorRadius,
            c.Z() + majorVec.Z() * majorRadius);
        major = InterOp::WriterGeometryConvertHelper::ConvertPoint(majorPoint);

        // startAngle = curveEllipse->FirstParameter();
        // endAngle = curveEllipse->LastParameter();
        startAngle = fp;
        endAngle = lp;

        // FIXME : 使用 api_mk_ed_ellipse
        api_curve_ellipse(center, major, ratio, startAngle, endAngle, res);
        return res;
    }

    EDGE *ConvertCircle(std::shared_ptr<Geom3Curve> curve, double fp, double lp)
    {
        auto curveCircle = std::dynamic_pointer_cast<AMCAX::Geom3Circle>(curve);
        auto curveTrimCircle = std::dynamic_pointer_cast<AMCAX::Geom3TrimmedCurve>(curveCircle);

        // 获取圆心
        AMCAX::Point3 _center = curveCircle->Location();
        SPAposition center = InterOp::WriterGeometryConvertHelper::ConvertPoint(_center);

        // 获取单位法向量
        AMCAX::Axis3 axis = curveCircle->Axis();
        SPAvector _normal = InterOp::WriterGeometryConvertHelper::ConvertVector(axis);
        SPAunit_vector unitNormal = normalise(_normal);

        // 获取长轴向量
        
        AMCAX::Point3 _major;
        AMCAX::Point3 _minor;
        curveCircle->D0(fp, _major);
        curveCircle->D0(lp, _minor);
        AMCAX::Vector3 majorVec(_major[0] - _center[0], _major[1] - _center[1], _major[2] - _center[2]);
        SPAvector major = InterOp::WriterGeometryConvertHelper::ConvertVector(majorVec);

        SPAposition pt1 = InterOp::WriterGeometryConvertHelper::ConvertPoint(_major);
        SPAposition pt2 = InterOp::WriterGeometryConvertHelper::ConvertPoint(_minor);

        double radius = curveCircle->Radius();
        double ratio = 1.0;
        double startAngle = fp ;
        double endAngle = lp;
        EDGE *res;
        api_curve_arc_center_edge(center,pt1,pt2,&unitNormal,res);
        return res;
    }

    EDGE *ConvertBSplineCurve(std::shared_ptr<Geom3Curve> curve, double fp, double lp)
    {

        auto curveBSpline = std::dynamic_pointer_cast<AMCAX::Geom3BSplineCurve>(curve);
        
        
        // 控制点
        auto &controlPoints = curveBSpline->Poles();
        std::vector<SPAposition> posArray(controlPoints.size());
        for (int i = 0; i < controlPoints.size(); ++i)
        {
            const AMCAX::Point3 &src = controlPoints[i];
            posArray[i] = InterOp::WriterGeometryConvertHelper::ConvertPoint(src);
        }

        // 权重
        auto &weights = curveBSpline->Weights();

        // 结点
        auto &knots = curveBSpline->Knots();
        auto &multis = curveBSpline->Multiplicities();
        std::vector<double> spaKnots;
        for (size_t i = 0; i < knots.size(); ++i)
        {
            for (int j = 0; j < multis[i]; ++j)
            {
                spaKnots.push_back(knots[i]);
            }
        }
        // 结点分布
        int degree = curveBSpline->Degree();
        int rational = curveBSpline->IsRational() ? 1 : 0;
        int closed = curveBSpline->IsClosed() ? 1 : 0;
        int periodic = curveBSpline->IsPeriodic() ? 1 : 0;



  
        EDGE *res;
        auto outcome = api_mk_ed_int_ctrlpts(
            degree,     // degree
            rational, // TRUE if rational control points
            closed,   // TRUE if closed curve
            periodic, // TRUE if periodic curve
            posArray.size(),            // number of control points in array
            posArray.data(),            // array of control points
            weights.data(),             // array of weights
            -1.0,                       // identical points if within this tolerance
            spaKnots.size(),            // number of knots in array
            spaKnots.data(),            // array of knots
            -1.0,                       // identical knots if within this tolerance
            res                         // edge returned
        );
        if (!outcome.ok())
        {
            LOG_WARN("{}", outcome.get_error_info()->error_message());
        }
        return res;
    }

    EDGE *ConvertHelix(std::shared_ptr<Geom3Curve> curve)
    {
        EDGE *res;
        SPAposition axisStart, axisEnd;
        SPAvector startDir;
        double radius, threadDistance;

        double startParam = curve->FirstParameter(); // 起始参数
        double endParam = curve->LastParameter();    // 结束参数

        AMCAX::Point3 startPoint = curve->Value(startParam); // 起点
        AMCAX::Point3 endPoint = curve->Value(endParam);     // 终点
        // 转换为 SPAposition
        axisStart = InterOp::WriterGeometryConvertHelper::ConvertPoint(startPoint);
        axisEnd = InterOp::WriterGeometryConvertHelper::ConvertPoint(endPoint);

        AMCAX::Vector3 startTangent, endTangent;
        // 构造单位向量
        SPAunit_vector start(startPoint.X(), startPoint.Y(), startPoint.Z()); // 直接传递三个分量
        SPAunit_vector end(endPoint.X(), endPoint.Y(), endPoint.Z());         // direction at end or NULL
        curve->D1(startParam, startPoint, startTangent);                      // 获取起点处的点和切线方向
        curve->D1(endParam, endPoint, endTangent);
        // 转换为 SPAvector
        startDir = InterOp::WriterGeometryConvertHelper::ConvertVector(startTangent);

        // 获取螺旋线的半径和螺距
        std::shared_ptr<helix> helixCurve = std::dynamic_pointer_cast<helix>(curve);
        if (!helixCurve)
        {
            // 如果曲线不是螺旋线类型，返回错误或抛出异常
            throw std::runtime_error("The provided curve is not a helix.");
        }

        radius = helixCurve->radius();
        threadDistance = helixCurve->pitch();

        // 获取手性（假设 z 分量表示手性）
        int rightHand = (startTangent.Z() > 0) ? 1 : -1;
        api_edge_helix(axisStart, axisEnd, startDir, radius, threadDistance, rightHand, res);
        return res;
    }

    FACE *ConvertFace(const AMCAX::TopoFace &face)
    {
        std::shared_ptr<Geom3Surface> surface = TopoTool::Surface(face);
        AMCAX::SurfaceType surfaceType = surface->Type();
        LOG_DEBUG("surfaceType:{}", surfaceTypeToString(surfaceType));
        if (surfaceType == AMCAX::SurfaceType::Plane)
        {
            return ConvertPlane(face);
        }
        else if (surfaceType == AMCAX::SurfaceType::Cone)
        {
            return ConvertCone(face);
        }
        else if (surfaceType == AMCAX::SurfaceType::Cylinder)
        {
            return ConvertCylinder(face);
        }
        else if (surfaceType == AMCAX::SurfaceType::Sphere)
        {
            return ConvertSphere(face);
        }
        else if (surfaceType == AMCAX::SurfaceType::Torus)
        {
            return ConvertTorus(face);
        }
        else if (surfaceType == AMCAX::SurfaceType::BSplineSurface)
        {
            return ConvertBsurface(face);
        }
        else if (surfaceType == AMCAX::SurfaceType::TrimmedSurface)
        {
            return ConvertTrimmedSurface(face);
      
        }
        else
        {
            LOG_ERROR("Unsupported surface type: {}", surfaceTypeToString(surfaceType));
        }
        return nullptr;
    }

    FACE *ConvertPlane(const AMCAX::TopoFace &face)
    {
        std::shared_ptr<Geom3Surface> surface = TopoTool::Surface(face);
        auto surfacePlane = std::dynamic_pointer_cast<Geom3Plane>(surface);
        SPAvector spav = InterOp::WriterGeometryConvertHelper::ConvertVector(surfacePlane->Axis());
        SPAunit_vector unitNormal = normalise(spav);
        SPAposition origin = InterOp::WriterGeometryConvertHelper::ConvertPoint(surfacePlane->Location());

        PLANE *plane = new PLANE(origin, unitNormal);
        LOOP *firstLoop = GetFaceLoop(face);
        REVBIT faceSense = face.Orientation() == AMCAX::OrientationType::Forward ? FORWARD : REVERSED;
        FACE *currentFace = new FACE(firstLoop, NULL, plane, faceSense);
        return currentFace;
    }

    FACE *ConvertCone(const AMCAX::TopoFace &face)
    {
        std::shared_ptr<Geom3Surface> surface = TopoTool::Surface(face);
        std::shared_ptr<Geom3ConicalSurface> surfaceCone = std::dynamic_pointer_cast<Geom3ConicalSurface>(surface);
        AMCAX::Point3 location = surfaceCone->Location(); // 圆柱中心
        AMCAX::Axis3 axis = surfaceCone->Axis();          // 从圆柱中心出发的法向轴
        double radius = surfaceCone->Radius();            // 基准半径
        AMCAX::Frame3 frame = surfaceCone->Position();    // 获取坐标系
        double theta = surfaceCone->SemiAngle(); 
        SPAposition center = InterOp::WriterGeometryConvertHelper::ConvertPoint(location);
        SPAvector normal1 = InterOp::WriterGeometryConvertHelper::ConvertVector(axis);
        SPAvector unitmajAxis = InterOp::WriterGeometryConvertHelper::ConvertVector(frame.XAxis());
        SPAunit_vector unitnormal = normalise(normal1);

        CONE *cylinder = new CONE(center,unitnormal,unitmajAxis *radius,1,sin(theta),cos(theta));   
        LOOP *firstLoop = GetFaceLoop(face);
        REVBIT faceSense = face.Orientation() == AMCAX::OrientationType::Forward ? FORWARD : REVERSED;
        FACE *currentFace = new FACE(firstLoop, NULL, cylinder, faceSense);
        return currentFace;
    }

    
    FACE *ConvertCylinder(const AMCAX::TopoFace &face)
    {
        std::shared_ptr<Geom3Surface> surface = TopoTool::Surface(face);
        std::shared_ptr<Geom3CylindricalSurface> surfaceCylinder = std::dynamic_pointer_cast<Geom3CylindricalSurface>(surface);
        AMCAX::Point3 location = surfaceCylinder->Location(); // 圆柱中心
        AMCAX::Axis3 axis = surfaceCylinder->Axis();          // 从圆柱中心出发的法向轴
        double radius = surfaceCylinder->Radius();            // 基准半径
        AMCAX::Frame3 frame = surfaceCylinder->Position();    // 获取坐标系
        SPAposition center = InterOp::WriterGeometryConvertHelper::ConvertPoint(location);
        SPAvector normal1 = InterOp::WriterGeometryConvertHelper::ConvertVector(axis);
        SPAvector unitmajAxis = InterOp::WriterGeometryConvertHelper::ConvertVector(frame.XAxis());
        SPAunit_vector unitnormal = normalise(normal1);
        
        CONE *cylinder = new CONE(center,unitnormal,unitmajAxis *radius);
        LOOP *firstLoop = GetFaceLoop(face);
        REVBIT faceSense = face.Orientation() == AMCAX::OrientationType::Forward ? FORWARD : REVERSED;
        FACE *currentFace = new FACE(firstLoop, NULL, cylinder, faceSense);
        return currentFace;
    }


    FACE *ConvertSphere(const AMCAX::TopoFace &face)
    {
        std::shared_ptr<Geom3Surface> surface = TopoTool::Surface(face);
        auto surfaceSphere = std::dynamic_pointer_cast<Geom3SphericalSurface>(surface);

        // 球心坐标
        AMCAX::Point3 location = surfaceSphere->Location();
        SPAposition center = InterOp::WriterGeometryConvertHelper::ConvertPoint(location);
        double radius = surfaceSphere->Radius(); // 半径

        SPHERE * sphere = new SPHERE(center, radius);
        LOOP *firstLoop = GetFaceLoop(face);
        REVBIT faceSense = face.Orientation() == AMCAX::OrientationType::Forward ? FORWARD : REVERSED;
        FACE *currentFace = new FACE(firstLoop, NULL, sphere, faceSense);
        return currentFace;
    }

    FACE *ConvertTrimmedSurface(const AMCAX::TopoFace &face)
    {
        std::shared_ptr<Geom3Surface> surface = TopoTool::Surface(face);
        auto surfaceSphere = std::dynamic_pointer_cast<Geom3TrimmedSurface>(surface);
        auto b=surfaceSphere->BasisSurface();
        FACE *currentFace;
        auto type=b->Type();
        if(type==AMCAX::SurfaceType::Sphere)
        {
            auto c=std::dynamic_pointer_cast<Geom3SphericalSurface>(b);
            // 球心坐标
            AMCAX::Point3 location = c->Location();
            SPAposition center = InterOp::WriterGeometryConvertHelper::ConvertPoint(location);

            SPHERE * s = new SPHERE(center, c->Radius());
            LOOP *firstLoop = GetFaceLoop(face);
            REVBIT faceSense = face.Orientation() == AMCAX::OrientationType::Forward ? FORWARD : REVERSED;
            currentFace = new FACE(firstLoop, NULL, s, faceSense);
            return currentFace;
        }
        else //有待丰富
        {
            return currentFace;
        }
    }
    FACE *ConvertTorus(const AMCAX::TopoFace &face)
    {
        std::shared_ptr<Geom3Surface> surface = TopoTool::Surface(face);
        auto surfaceTorus = std::dynamic_pointer_cast<Geom3ToroidalSurface>(surface);

        AMCAX::Point3 location = surfaceTorus->Location(); // 位置点
        AMCAX::Axis3 axis = surfaceTorus->Axis();          // 法向轴

        double majorRadius = surfaceTorus->MajorRadius();  // 大半径
        double minorRadius = surfaceTorus->MinorRadius();  // 小半径
        // ACIS
        FACE *res;
        SPAposition center = InterOp::WriterGeometryConvertHelper::ConvertPoint(location);
        SPAvector normal = InterOp::WriterGeometryConvertHelper::ConvertVector(axis);

        SPAunit_vector unitnormal = normalise(normal);

        TORUS *torus = new TORUS(center, unitnormal, majorRadius, minorRadius);
        LOOP *firstLoop = GetFaceLoop(face);
        REVBIT faceSense = face.Orientation() == AMCAX::OrientationType::Forward ? FORWARD : REVERSED;
        FACE *currentFace = new FACE(firstLoop, NULL, torus, faceSense);

        return currentFace;

    }

    FACE *ConvertBsurface(const AMCAX::TopoFace &face)
    {
        std::shared_ptr<Geom3Surface> surface = TopoTool::Surface(face);
        auto surfaceBsurface = std::dynamic_pointer_cast<Geom3BSplineSurface>(surface);
        

        // 控制点
        const Array2<Point3> &controlPoints = surfaceBsurface->Poles();
        const AMCAX::Point3 *controlPointsPtr = controlPoints.Data();
        std::vector<SPAposition> posArray(controlPoints.Size());
        for (int i = 0; i < controlPoints.Size(); ++i)
        {
            const AMCAX::Point3 &src = controlPointsPtr[i];
            posArray[i] = InterOp::WriterGeometryConvertHelper::ConvertPoint(src);
        }

        // 权重
        const Array2<double> &weights = surfaceBsurface->Weights();

        // 结点
        auto &uKnots = surfaceBsurface->UKnots();
        auto &vKnots = surfaceBsurface->VKnots();
        auto &uMult = surfaceBsurface->UMultiplicities();
        auto &vMult = surfaceBsurface->VMultiplicities();

        std::vector<double> uResult;
        for (size_t i = 0; i < uKnots.size(); ++i)
        {
            for (int j = 0; j < uMult[i]; ++j)
            {
                uResult.push_back(uKnots[i]);
            }
        }

        std::vector<double> vResult;
        for (size_t i = 0; i < vKnots.size(); ++i)
        {
            for (int j = 0; j < vMult[i]; ++j)
            {
                vResult.push_back(vKnots[i]);
            }
        }



        int degree_u = surfaceBsurface->UDegree();
        bool rational_u = surfaceBsurface->IsURational();
        int form_u = surfaceBsurface->IsUClosed()? 1:0;
        int pole_u = 0;
        int num_ctrlpts_u = surfaceBsurface->NUPoles();
        int degree_v = surfaceBsurface->VDegree();
        bool rational_v = surfaceBsurface->IsVRational();
        int form_v = surfaceBsurface->IsVClosed()? 1:0;
        int pole_v = 0;
        int num_ctrlpts_v = surfaceBsurface->NVPoles();

        const double *weightsPtr =  weights.Data();

        
        
        bs3_surface bs3surface = bs3_surface_from_ctrlpts(
            degree_u,                           //int 	degree_u, 
            rational_u,                         //logical 	rational_u,
            form_u,                                                  //int 	form_u,
            pole_u,                                                  //int & 	pole_u,
            num_ctrlpts_u,                             //int 	num_ctrlpts_u,
            degree_v,
            rational_v,
            form_v,
            pole_v,
            num_ctrlpts_v,
            posArray.data(),                                        //const SPAposition 	ctrlpts[],
            weightsPtr,                                         //const double 	weights[],
            -1.0,                                                   //double 	ctrlpt_tol,
            uResult.size(),                                         //int 	num_knots_u,
            uResult.data(),                                         //const double 	knots_u[],
            vResult.size(),                                         //int 	num_knots_v,
            vResult.data(),                                         //const double 	knots_v[],
            -1.0                                                    //double 	knot_tol 
        );
        
        
        
        spline *spl = new spline(bs3surface);
        SPLINE *SplineSurf = new SPLINE(*spl);
        LOOP *firstLoop = GetFaceLoop(face);

        REVBIT faceSense = face.Orientation() == AMCAX::OrientationType::Forward ? FORWARD : REVERSED;
        FACE *currentFace = new FACE(firstLoop, NULL, SplineSurf, faceSense);
        return currentFace;
    }
    
    LOOP* GetFaceLoop(const AMCAX::TopoFace &face)
    {
        LOOP *prevLoop = nullptr;
        LOOP *firstLoop = nullptr;
        AMCAX::TopoExplorer exp_wire;
        for (exp_wire.Init(face, AMCAX::ShapeType::Wire); exp_wire.More(); exp_wire.Next())
        {
            ENTITY_LIST allEdgeList;
     
            COEDGE *prevCoedge = nullptr;
            COEDGE *firstCoedge = nullptr;
            const TopoWire &wire = TopoCast::Wire(exp_wire.Current());
            AMCAX::TopoExplorer exp_edge;

            AMCAX::Point3 this_endPoint,first_startPoint;
            int i=0;
            for (exp_edge.Init(wire, AMCAX::ShapeType::Edge); exp_edge.More(); exp_edge.Next())
            {
             
                const TopoEdge &edge = TopoCast::Edge(exp_edge.Current());
                REVBIT sense = edge.Orientation() == AMCAX::OrientationType::Reversed ? REVERSED : FORWARD; 
                double fp, lp;
                std::shared_ptr<Geom3Curve> curve = TopoTool::Curve(edge, fp, lp);
                if(curve == nullptr)
                {
                    LOG_ERROR("curve is null") ;
                    continue;
                }

                AMCAX::Point3 startPoint,endPoint;
                curve->D0(fp,startPoint);
                curve->D0(lp,endPoint);
                

                EDGE *currentEdge = ConvertEdge(edge);

                
                if(currentEdge == nullptr)
                {
                    continue;
                }

                if(i!=0)
                {
                    if(startPoint.IsEqual(this_endPoint, 1e-4))
                    {
                        sense = FORWARD; // 如果起点和上一个边的终点相同，则方向为FORWARD
                    }
                    else
                    {
                        sense = REVERSED; // 否则方向为REVERSED
                    }
                }
                else
                {
                    first_startPoint = startPoint; // 记录第一个边的起点
                }
                this_endPoint = endPoint;
                i++;
                
                COEDGE *currentCoedge = nullptr;

                auto temp = exp_edge;
                temp.Next();
                auto NotLast = temp.More();

                if(NotLast)
                {
                    if(i == 0)
                    {
                        currentCoedge = new COEDGE(currentEdge, FORWARD, prevCoedge, nullptr);
                    }
                    else
                    {
                        currentCoedge = new COEDGE(currentEdge, sense, prevCoedge, nullptr);
                    }

                }
                else{
                    if(endPoint.IsEqual(first_startPoint, 1e-4))
                    {
                        sense = REVERSED; // 如果最后一个边的终点和第一个边的起点相同，则方向为FORWARD
                    }
                    else
                    {
                        sense = FORWARD; // 否则方向为REVERSED
                    }
                    currentCoedge = new COEDGE(currentEdge, sense, prevCoedge, firstCoedge);
                }
                if(!prevCoedge)
                {
                    firstCoedge = currentCoedge;
                }
                prevCoedge = currentCoedge;
   
              
            }

            LOOP *currentLoop = new LOOP(firstCoedge, NULL);
            if (!prevLoop)
            {
                firstLoop = currentLoop;
            }
            else
            {
                prevLoop->set_next(currentLoop);
            }
            prevLoop = currentLoop;
        }
        return firstLoop;
    }
}

AMCAX_EXCHANGE_NAMESPACE_END